/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.databinding.tool.reflection

import android.databinding.tool.reflection.java.JavaAnalyzer
import org.junit.Before
import org.junit.Test
import org.junit.Assert.assertTrue

class JavaClassTest {

  @Before
  fun setUp() = JavaAnalyzer.initForTests()

  @Test
  fun getAllMethods() {
    val modelClass = ModelAnalyzer.getInstance().findClass("java.lang.String", null)!!
    val methods = modelClass.allMethods

    // NOTE: We don't care about any particular method that we're testing against here; we're just
    // sampling to make sure that methods are being exposed with expected metadata.
    methods
      .filter { it.isPublic }
      .let { publicMethods ->
        // instance methods
        assertTrue(publicMethods.any { it.name == "charAt" })
        assertTrue(publicMethods.any { it.name == "startsWith" })
        // methods from base class
        assertTrue(publicMethods.any { it.name == "getClass" })
        assertTrue(publicMethods.any { it.name == "wait" })
        // static methods
        assertTrue(publicMethods.any { it.name == "format" })
        assertTrue(publicMethods.any { it.name == "valueOf" })
      }

    // private methods exist
    assertTrue(methods.any { !it.isPublic && !it.isProtected })
  }

  @Test
  fun getAllFields() {
    val modelClass = ModelAnalyzer.getInstance().findClass("java.awt.Rectangle", null)!!
    val fields = modelClass.allFields

    // NOTE: We don't care about any particular field that we're testing against here; we're just
    // sampling to make sure that fields are being exposed with expected metadata.
    fields
      .filter { it.isPublic }
      .let { publicFields ->
        // instance
        assertTrue(publicFields.any { it.name == "width"})
        assertTrue(publicFields.any { it.name == "height"})
        // static
        assertTrue(publicFields.any { it.name == "OUT_LEFT" })
      }

    // private fields exist
    assertTrue(fields.any { !it.isPublic })
  }
}